package io.github.wppli.infrastructure.persistent.repository;

import io.github.wppli.domain.pay.event.OrderBehaviorsEvent;
import io.github.wppli.domain.pay.model.aggregates.CreateOrderAggregate;
import io.github.wppli.domain.pay.model.entity.*;
import io.github.wppli.domain.pay.model.valobj.OrderStatusVO;
import io.github.wppli.domain.pay.model.valobj.PayStatusVO;
import io.github.wppli.domain.pay.repository.IOrderRepository;
import io.github.wppli.infrastructure.event.EventPublisher;
import io.github.wppli.infrastructure.persistent.dao.IProductDao;
import io.github.wppli.infrastructure.persistent.dao.IProductExtendDao;
import io.github.wppli.infrastructure.persistent.dao.IProductOrderDao;
import io.github.wppli.infrastructure.persistent.dao.IProductSkuDao;
import io.github.wppli.infrastructure.persistent.po.Product;
import io.github.wppli.infrastructure.persistent.po.ProductOrder;
import io.github.wppli.infrastructure.persistent.po.ProductSku;
import io.github.wppli.types.event.BaseEvent;
import io.github.wppli.types.snow.SnowflakeIdGenerator;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;

/**
 * @author li--jiaqiang 2025−03−19
 */
@Slf4j
@Repository
@AllArgsConstructor
public class OrderRepository implements IOrderRepository {

    private final IProductOrderDao productOrderDao;
    private final IProductDao productDao;
    private final IProductSkuDao productSkuDao;
    private final EventPublisher eventPublisher;
    private final SnowflakeIdGenerator snowflakeIdGenerator;
    private final IProductExtendDao productExtendDao;

    /**
     * 根据购物车查询未支付的订单
     * @param shopCartEntity 购物车实体
     * @return 未支付的订单实体
     */
    @Override
    public UnpaidOrderEntity queryUnpaidOrder(ShopCartEntity shopCartEntity) {
        // 订单持久化对象
        ProductOrder productOrder = new ProductOrder();
        productOrder.setUserId(shopCartEntity.getUserId());
        productOrder.setProductId(shopCartEntity.getProductId());
        /* <!-- queryUnpaidOrder 查询未支付订单 --> */
        ProductOrder unpaidOrder = productOrderDao.queryUnpaidOrder(productOrder);

        if (null == unpaidOrder) {
            // 该用户对于该商品, 没有未支付订单, 返回 null 即可.
            return null;
        }
        // 存在未支付订单, 返回该订单信息
        return UnpaidOrderEntity.builder()
                .userId(shopCartEntity.getUserId())
                .orderId(unpaidOrder.getOrderId())
                .productName(unpaidOrder.getProductName())
                .totalAmount(unpaidOrder.getTotalAmount())
                .payUrl(unpaidOrder.getPayUrl())
                .payStatus(PayStatusVO.get(unpaidOrder.getPayStatus()))
                .build();
    }

    @Override
    public void saveOrder(CreateOrderAggregate aggregate) {
        // 用户 userId
        Long userId = aggregate.getUserId();
        // 商品实体
        ProductEntity product = aggregate.getProduct();
        // 订单实体
        OrderEntity order = aggregate.getOrder();
        // 订单持久化实体
        ProductOrder productOrder = new ProductOrder();
        productOrder.setUserId(userId);
        productOrder.setProductId(product.getProductId());
        productOrder.setProductName(product.getProductName());
        productOrder.setOrderId(order.getOrderId());
        productOrder.setOrderTime(order.getOrderTime());
        // 过期时间为10分钟
        productOrder.setExpireTime(order.getOrderTime().plusMinutes(10));
        productOrder.setOrderStatus(order.getOrderStatus().getCode());
        productOrder.setTotalAmount(order.getTotalAmount());
        productOrder.setPayType(order.getPayTypeVO().getCode());
        productOrder.setPayStatus(PayStatusVO.WAIT.getCode());

        /* <!-- 插入订单 --> */
        log.info("订单: {}", productOrder);
        productOrderDao.insert(productOrder);
    }

    @Override
    public void updateOrderPayInfo(PayOrderEntity payOrderEntity) {
        // 构造支付持久化实体
        ProductOrder productOrder = new ProductOrder();
        productOrder.setUserId(payOrderEntity.getUserId());
        productOrder.setOrderId(payOrderEntity.getOrderId());
        productOrder.setPayUrl(payOrderEntity.getPayUrl());
        // 等待支付
        productOrder.setPayStatus(payOrderEntity.getPayStatus().getCode());
        productOrderDao.updateOrderPayInfo(productOrder);
    }

    @Override
    public boolean changeOrderPaySuccess(String orderId, String transactionId, BigDecimal totalAmount, Date payTime) {
        // 创建订单持久化对象
        ProductOrder productOrder = new ProductOrder();
        productOrder.setOrderId(orderId); // 订单id
        productOrder.setPayAmount(totalAmount); // 总金额
        productOrder.setPayTime(payTime); // 支付时间
        productOrder.setTransactionId(transactionId); // 交易单号
        int count = productOrderDao.changeOrderPaySuccess(productOrder);
        return count == 1;
    }

    @Override
    public CreateOrderAggregate queryOrder(String orderId) {
        ProductOrder productOrder = productOrderDao.queryOrder(orderId);

        ProductEntity product = new ProductEntity();
        product.setProductId(productOrder.getProductId());
        product.setProductName(productOrder.getProductName());

        OrderEntity order = new OrderEntity();
        order.setOrderId(productOrder.getOrderId());
        order.setOrderTime(productOrder.getOrderTime());
        order.setOrderStatus(OrderStatusVO.get(productOrder.getOrderStatus()));
        order.setTotalAmount(productOrder.getTotalAmount());

        CreateOrderAggregate createOrderAggregate = new CreateOrderAggregate();
        createOrderAggregate.setUserId(productOrder.getUserId());
        createOrderAggregate.setOrder(order);
        createOrderAggregate.setProduct(product);

        return createOrderAggregate;
    }

    @Override
    public List<String> queryReplenishmentOrder() {
        return productOrderDao.queryReplenishmentOrder();
    }

    @Override
    public List<String> queryNoPayNotifyOrder() {
        return productOrderDao.queryNoPayNotifyOrder();
    }

    /**
     * 查询超时15分钟，未支付订单
     */
    @Override
    public List<String> queryTimeoutCloseOrderList() {
        return productOrderDao.queryTimeoutCloseOrderList();
    }

    @Override
    public boolean changeOrderClose(String orderId) {
        return productOrderDao.changeOrderClose(orderId);
    }

    @Override
    public List<ProductEntity> queryProductList() {
        List<Product> productList =  productDao.queryProductList();
        if (productList.isEmpty()) {
            return Collections.emptyList();
        }
        List<ProductEntity> productEntityList = new ArrayList<>(productList.size());
        for (Product product : productList) {
            ProductEntity productEntity = new ProductEntity();
            productEntity.setProductId(product.getId());
            productEntity.setProductName(product.getName());
            productEntity.setProductDesc(product.getDescription());
            productEntity.setPrice(product.getPrice());
            productEntityList.add(productEntity);
        }
        return productEntityList;
    }

    @Override
    public void sendOrderBehaviorsMessage(String topic, BaseEvent.EventMessage<OrderBehaviorsEvent.OrderBehaviorsEntity> orderBehaviorsEntityEventMessage) {
        eventPublisher.publish(topic, orderBehaviorsEntityEventMessage);
    }

    @Override
    public void saveProductSku(ProductEntity productEntity) {
        ProductSku productSku = new ProductSku();
        productSku.setSkuId(snowflakeIdGenerator.nextId());
        productSku.setProductId(productEntity.getProductId());
        productSku.setProductName(productEntity.getProductName());
        productSku.setPrice(productEntity.getPrice());
        productSku.setSpecs(productEntity.getSpecs());
        productSku.setImage(productEntity.getMainImage());
        productSku.setStock(productSku.getStock());

        productSkuDao.insert(productSku);
    }

    @Override
    public void createViewOrder(Long productId) {
        productExtendDao.createViewOrder(productId);
    }

    @Override
    public void createBuyOrder(Long productId, Integer count) {
        productExtendDao.createSalesOrder(productId, count);
    }
}